/**
 * 
 * gislin
 * 2017年5月4日
 */
package com.hrt.datasender.web.monitordata;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.btcode.db.conver.DefaultValueConver;
import com.btcode.db.conver.IValueConver;
import com.btcode.db.result.Row;
import com.btcode.db.sqlparameter.SQLParameterList;
import com.hrt.datasender.datadao.model.BcDeviceMonitorParamModel;
import com.hrt.datasender.datadao.service.BcDeviceMonitorParamService;
import com.hrt.datasender.datastorage.StorageDataType;
import com.hrt.datasender.datastorage.strategy.monitordata.MonitorDataStrategy;
import com.hrt.db.DBManager;

/**
 * @author gislin 2017年5月4日
 */
public final class MonitorDataUtil {

    private static volatile MonitorDataUtil instance;

    private MonitorDataUtil() {

    }

    public static MonitorDataUtil getInstance() {
        if (instance == null) {
            synchronized (MonitorDataUtil.class) {
                if (instance == null) {
                    instance = new MonitorDataUtil();
                }
            }
        }
        return instance;
    }

    /**
     * 获取站点报警阈值
     *
     *            TODO
     *            TODO
     * @return
     */
    public List<PollutantsModel> getPollInfo() {

        List<BcDeviceMonitorParamModel> params = BcDeviceMonitorParamService.getInstance().getParamByStation();

        List<PollutantsModel> pollInfos = new ArrayList<>();

        for (BcDeviceMonitorParamModel poll : params) {
            PollutantsModel pollModel = new PollutantsModel();

            pollModel.setUnit(poll.getUnit());
            pollModel.setPollCode(poll.getParamCodeBus());
            pollInfos.add(pollModel);

        }

        return pollInfos;
    }

    /**
     * 数据缺失留白 gislin 2017年4月26日
     * 
     * @param historyData
     *            业务类型，不同业务相同数据类型的数据间隔可能不一样，这里作为一个拓展点
     * @param startDate
     * @param endDate
     * @return
     */
    public List<Row> fixMissData(List<Row> historyData, MonitorDataStrategy strategy, Date startDate, Date endDate) {

        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        /**
         * 存放数据留白的最终结果
         */
        List<Row> fixedResult = new ArrayList<>();
        Iterator<Row> historyDataIterator = historyData.iterator();

        /**
         * 顺序取historyData中的数据时间，以此为基准 和endCal作比较，判断缺了哪些数据
         */
        Calendar nextDataEndCal = Calendar.getInstance();

        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);

        Calendar tempEndCal = Calendar.getInstance();
        tempEndCal.setTime(endDate);
        tempEndCal.set(Calendar.SECOND, 0);
        tempEndCal.set(Calendar.MINUTE, 0);

        IValueConver valueConver = new DefaultValueConver();

        if (strategy.getDataType().equals(StorageDataType.DAY)) {
            tempEndCal.set(Calendar.HOUR_OF_DAY, 0);
            startCal.add(Calendar.SECOND,-1);
        }

        if (strategy.getDataType().equals(StorageDataType.MINUTES)) {
            if(strategy.getDataInterval()==300){
                tempEndCal.set(Calendar.MINUTE, 55);
            }
            else{
                tempEndCal.set(Calendar.MINUTE, 50);
            }
        }

        if(strategy.getDataType().equals(StorageDataType.HOUR)){
            startCal.add(Calendar.SECOND,-1);
        }

        while (!tempEndCal.before(startCal)) {

            Row currentRow = null;
            Date nextEndDataDate = null;

            if (historyDataIterator.hasNext()) {
                currentRow = historyDataIterator.next();
            }
            /**
             * 取到第一个日期
             */
            if (currentRow == null) {
                nextEndDataDate = startCal.getTime();
            } 
            else {
                nextEndDataDate = valueConver.converToDate(currentRow.get("DATATIME"));
            }
            nextDataEndCal.setTime(nextEndDataDate);
            /**
             * 分钟秒设置为0，变成整点数据，方便比较，有些数据时间不是刚好整点
             */
            nextDataEndCal.set(Calendar.SECOND, 0);

            if (!tempEndCal.before(nextDataEndCal) && !tempEndCal.equals(nextDataEndCal)) {
                /**
                 * 如果条件成立，代表有数据空白，插入空数据
                 */
                while (!tempEndCal.before(nextDataEndCal) && !tempEndCal.equals(nextDataEndCal)) {
                    Row row = new Row();
                    row.put("DATATIME",new Timestamp(tempEndCal.getTimeInMillis()));
                    fixedResult.add(row);
                    System.out.println("endCal:" + sf.format(tempEndCal.getTime()) + ",nextEndCal:"
                            + sf.format(nextDataEndCal.getTime()) + ",插入");
                    tempEndCal = getNextCalendar(tempEndCal, strategy);
                }
                tempEndCal = getNextCalendar(tempEndCal, strategy);
                fixedResult.add(currentRow);
                System.out.println("endCal:" + sf.format(tempEndCal.getTime()) + ",nextEndCal:"
                        + sf.format(nextDataEndCal.getTime()));
            }
            else {
                /**
                 * 否则直接把当前行加入
                 */
                tempEndCal = getNextCalendar(tempEndCal, strategy);
                System.out.println("endCal:" + sf.format(tempEndCal.getTime()) + ",nextEndCal:"
                        + sf.format(nextDataEndCal.getTime()));
                fixedResult.add(currentRow);
            }
        }

        return fixedResult;
    }

    /**
     * 查询历史数据
     *
     * @param startDate
     *            开始时间
     * @param endDate
     *            结束时间
     * @param tableName
     *            查询的表名称
     * @param dataFields
     *            要查询的字段
     * @return
     */
    public MonitorDataModel getHistoryData(Date startDate, Date endDate, String tableName, String[] dataFields) {

        long startTime = System.currentTimeMillis(); // 获取开始时间

        String fieldString = "";
        for (String field : dataFields) {
            fieldString += field + ",";
        }

        fieldString = fieldString.substring(0, fieldString.length() - 1);
        String sql = " select PARAM_CODE_BUS," + fieldString + ",DATATIME from " + tableName + " t \n "
                + "   	where datatime >= @start \n" + "			and datatime<= @end \n"
                + "			order by datatime desc ";

        SQLParameterList pc = new SQLParameterList();
        pc.put("start", startDate);
        pc.put("end", endDate);

        startTime = System.currentTimeMillis(); // 获取开始时间
        List<Row> result = DBManager.getDataExecuter().queryList(sql, pc);
        long endTime = System.currentTimeMillis(); // 获取结束时间
        System.out.println("sql查询时间： " + (endTime - startTime) + "ms");

        List<PollutantsModel> pollInfo = getPollInfo();

        MonitorDataModel dataModel = new MonitorDataModel();
        dataModel.setData(result);
        dataModel.setPollInfoList(pollInfo);

        return dataModel;
    }

    /**
     * 配合fixMissData方法，获取下一个时间 不同业务，不同数据，获选下一个时间的参数不一样 gislin 2017年4月26日
     *
     * @return
     */
    public Calendar getNextCalendar(Calendar cal, MonitorDataStrategy strategy) {

        cal.add(Calendar.SECOND, -1 * strategy.getDataInterval());
        return cal;
    }

}
